// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Matteo Perotti <mperotti@iis.ee.ethz.ch>
//         Basile Bougenot <bbougenot@student.ethz.ch>

#include "float_macros.h"
#include "vector_macros.h"

// Simple random test with similar values
void TEST_CASE1(void) {
  VSET(16, e16, m1);
  //               0.3474, -0.9888,  0.2810,  0.4199,  0.1704, -0.3772,  0.2998,
  //               0.7871, -0.2527, -0.8618,  0.2646,  0.5488, -0.3184, -0.3508,
  //               -0.3589, -0.3914
  VLOAD_16(v2, 0x358f, 0xbbe9, 0x347f, 0x36b8, 0x3174, 0xb609, 0x34cc, 0x3a4c,
           0xb40b, 0xbae5, 0x343c, 0x3864, 0xb518, 0xb59d, 0xb5be, 0xb643);
  //               0.0417,  0.3862, -0.9619, -0.5659,  0.1731,  0.4827,  0.7334,
  //               -0.7271, -0.9814,  0.8003, -0.4836,  0.5234, -0.8540,
  //               -0.2036, -0.8823,  0.2603
  VLOAD_16(v3, 0x2958, 0x362e, 0xbbb2, 0xb887, 0x318a, 0x37b9, 0x39de, 0xb9d1,
           0xbbda, 0x3a67, 0xb7bd, 0x3830, 0xbad5, 0xb284, 0xbb0f, 0x342a);
  //              -0.2739,  0.2146,  0.5264, -0.8853,  0.8877, -0.6748, -0.7563,
  //              -0.9634,  0.7451, -0.5166,  0.0698,  0.4790, -0.0681, -0.9746,
  //              0.2129,  0.9072
  VLOAD_16(v1, 0xb462, 0x32de, 0x3836, 0xbb15, 0x3b1a, 0xb966, 0xba0d, 0xbbb5,
           0x39f6, 0xb822, 0x2c77, 0x37aa, 0xac5b, 0xbbcc, 0x32d0, 0x3b42);
  asm volatile("vfnmsac.vv v1, v2, v3");
  //              -0.2883,  0.5967,  0.7969, -0.6475,  0.8584, -0.4927, -0.9761,
  //              -0.3911,  0.4971,  0.1733,  0.1978,  0.1917, -0.3401, -1.0459,
  //              -0.1038,  1.0088
  VCMP_U16(1, v1, 0xb49d, 0x38c6, 0x3a60, 0xb92e, 0x3ade, 0xb7e2, 0xbbcf,
           0xb642, 0x37f4, 0x318a, 0x3254, 0x3223, 0xb570, 0xbc2f, 0xaea4,
           0x3c09);

  VSET(16, e32, m1);
  //               0.11577118, -0.10074481,  0.13861528,  0.44782066,
  //               0.42196107, -0.67597556,  0.34948668, -0.87903690,
  //               -0.34136006, -0.19722189,  0.76997000, -0.68663412,
  //               0.45603558,  0.60629857, -0.86984915, -0.08019307
  VLOAD_32(v2, 0x3ded1971, 0xbdce534c, 0x3e0df12a, 0x3ee548c0, 0x3ed80b48,
           0xbf2d0cbc, 0x3eb2efeb, 0xbf610890, 0xbeaec6bf, 0xbe49f489,
           0x3f451cc1, 0xbf2fc741, 0x3ee97d7f, 0x3f1b3662, 0xbf5eae6f,
           0xbda43c43);
  //              -0.38970658,  0.40460527,  0.69067985, -0.98108912,
  //              0.47494572, -0.34277225, -0.54462087, -0.90492284, 0.60100728,
  //              -0.02819708, -0.46859986,  0.87238866,  0.46812481,
  //              0.49922746,  0.97036403,  0.04279163
  VLOAD_32(v3, 0xbec7879f, 0x3ecf286c, 0x3f30d065, 0xbf7b28a8, 0x3ef32c16,
           0xbeaf7fd8, 0xbf0b6c46, 0xbf67a906, 0x3f19db9d, 0xbce6fd92,
           0xbeefec52, 0x3f5f54dd, 0x3eefae0e, 0x3eff9abe, 0x3f7869c7,
           0x3d2f4647);
  //               0.79804420, -0.70010293, -0.51047552,  0.38566175,
  //               0.15318950,  0.15531392, -0.20705318, -0.82493448,
  //               0.12047531,  0.57526720,  0.23939800, -0.19725421,
  //               0.15403098,  0.03931713, -0.45930895, -0.15395784
  VLOAD_32(v1, 0x3f4c4ca0, 0xbf3339f2, 0xbf02ae86, 0x3ec57575, 0x3e1cddb5,
           0x3e1f0a9d, 0xbe5405c0, 0xbf532ee8, 0x3df6bbc3, 0x3f1344b6,
           0x3e7524c0, 0xbe49fd02, 0x3e1dba4c, 0x3d210b00, 0xbeeb2a8b,
           0xbe1da720);
  asm volatile("vfnmsac.vv v1, v2, v3");
  //               0.84316099, -0.65934104, -0.60621428,  0.82501376,
  //               -0.04721911, -0.07639174, -0.01671545, -1.62039506,
  //               0.32563519,  0.56970614,  0.60020584,  0.40175763,
  //               -0.05945060, -0.26336378,  0.38476136, -0.15052626
  VCMP_U32(2, v1, 0x3f57d966, 0xbf28ca93, 0xbf1b30dc, 0x3f53341a, 0xbd4168d3,
           0xbd9c7345, 0xbc88eed4, 0xbfcf691b, 0x3ea6b9a8, 0x3f11d843,
           0x3f19a717, 0x3ecdb32c, 0xbd738277, 0xbe86d79e, 0x3ec4ff71,
           0xbe1a238e);

  VSET(16, e64, m1);
  //              -0.1779684802061718,  0.1122733699429854, -0.0166033088608786,
  //              -0.0418350503858864,  0.0809510021720363, -0.9993917101510512,
  //              -0.2139048161619248,  0.7196716914796224,  0.6489783595942558,
  //              0.5950689618839839, -0.7376256302221853, -0.5442228345597713,
  //              -0.8234113806545975, -0.6424001059348645, -0.3817524674245201,
  //              -0.8801262923106541
  VLOAD_64(v2, 0xbfc6c7abd11a2788, 0x3fbcbdf2941de8b0, 0xbf91007532405e80,
           0xbfa56b675a77c100, 0x3fb4b93472e84630, 0xbfeffb0452dfc0ba,
           0xbfcb613ba6efa978, 0x3fe7078ced586224, 0x3fe4c46e43c89c1c,
           0x3fe30ace10450114, 0xbfe79aa110cfdc92, 0xbfe16a46018575da,
           0xbfea5962d2e21a3e, 0xbfe48e8aaabdfd5e, 0xbfd86ea1e6b05c10,
           0xbfec29fe9d3a5e2c);
  //               0.6809772463364707, -0.3512739833826983, -0.3746023351803702,
  //               -0.7912172181005324,  0.8292434726428350, 0.4103374079106952,
  //               -0.0850673796598582, -0.5834949864830523,
  //               -0.9215678788036654,  0.4412210589054084, 0.3537359089001260,
  //               -0.4889461402031243,  0.2341577339668230, 0.0593866008892341,
  //               -0.4825773777931026,  0.8989772522533539
  VLOAD_64(v3, 0x3fe5ca90cb4aba98, 0xbfd67b45dfa41e18, 0xbfd7f97c12a6b704,
           0xbfe951a6c578c3ac, 0x3fea89299b6d84b0, 0x3fda42f7d4d35178,
           0xbfb5c6f9cd987320, 0xbfe2abfdad8a63b6, 0xbfed7d7beb902fcc,
           0x3fdc3cf7409388b4, 0x3fd6a39bf009666c, 0xbfdf4ae4c06b61e4,
           0x3fcdf8e170bf19c0, 0x3fae67eba9479c60, 0xbfdee28c39da4ac0,
           0x3fecc46bf148d5ca);
  //               0.2213384305747967, -0.6962211546566610, -0.0896076892809434,
  //               -0.1334142611967066,  0.1988436916560323,
  //               -0.3391391007320459, -0.6137202819751713, 0.6759552396290200,
  //               -0.7798663937316326, -0.1025181838739857, 0.5296250728149803,
  //               0.8832422045338422,  0.8373555508937671, -0.8622529212135799,
  //               0.4241832213372883,  0.7769982087360683
  VLOAD_64(v1, 0x3fcc54d154555708, 0xbfe6477196411436, 0xbfb6f0878eee8940,
           0xbfc113b7f0547630, 0x3fc973b5c856db48, 0xbfd5b4747c9c185c,
           0xbfe3a398b77f3552, 0x3fe5a16ce1f8870a, 0xbfe8f4aa5e0a7552,
           0xbfba3ea1b6fbece0, 0x3fe0f2b047dc3902, 0x3fec438527dd6ef6,
           0x3feacb9dde46cf34, 0xbfeb9793702fc4f0, 0x3fdb25d161c9f510,
           0x3fe8dd2b58f24dc8);
  asm volatile("vfnmsac.vv v1, v2, v3");
  //               0.3425309161602823, -0.6567824407689892, -0.0958273275519495,
  //               -0.1665148733821233,  0.1317156015009752, 0.0709487030987733,
  //               -0.6319166041826899,  1.0958800635211576,
  //               -0.1817887834908719, -0.3650751413581792, 0.7905497455496533,
  //               0.6171465501654385,  1.0301636939103409, -0.8241029625112244,
  //               0.2399581166415165,  1.5682117246334322
  VCMP_U64(3, v1, 0x3fd5ec06cab1bfc9, 0xbfe5045c9bf61361, 0xbfb88823c5e61162,
           0xbfc5505bffbca57e, 0x3fc0dc0e8c68ea87, 0x3fb229b1b780ba72,
           0xbfe438a92b9872ef, 0x3ff188b9889296a1, 0xbfc744dad7efbbd3,
           0xbfd75d64202dd23c, 0x3fe94c2efadfe675, 0x3fe3bfaa1f3997d0,
           0x3ff07b8cecedf189, 0xbfea5f0d2d10b7b0, 0x3fceb6f293b149df,
           0x3ff917652d6811d0);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE2(void) {
  VSET(16, e16, m1);
  //               0.3474, -0.9888,  0.2810,  0.4199,  0.1704, -0.3772,  0.2998,
  //               0.7871, -0.2527, -0.8618,  0.2646,  0.5488, -0.3184, -0.3508,
  //               -0.3589, -0.3914
  VLOAD_16(v2, 0x358f, 0xbbe9, 0x347f, 0x36b8, 0x3174, 0xb609, 0x34cc, 0x3a4c,
           0xb40b, 0xbae5, 0x343c, 0x3864, 0xb518, 0xb59d, 0xb5be, 0xb643);
  //               0.0417,  0.3862, -0.9619, -0.5659,  0.1731,  0.4827,  0.7334,
  //               -0.7271, -0.9814,  0.8003, -0.4836,  0.5234, -0.8540,
  //               -0.2036, -0.8823,  0.2603
  VLOAD_16(v3, 0x2958, 0x362e, 0xbbb2, 0xb887, 0x318a, 0x37b9, 0x39de, 0xb9d1,
           0xbbda, 0x3a67, 0xb7bd, 0x3830, 0xbad5, 0xb284, 0xbb0f, 0x342a);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.2739,  0.2146,  0.5264, -0.8853,  0.8877, -0.6748, -0.7563,
  //              -0.9634,  0.7451, -0.5166,  0.0698,  0.4790, -0.0681, -0.9746,
  //              0.2129,  0.9072
  VLOAD_16(v1, 0xb462, 0x32de, 0x3836, 0xbb15, 0x3b1a, 0xb966, 0xba0d, 0xbbb5,
           0x39f6, 0xb822, 0x2c77, 0x37aa, 0xac5b, 0xbbcc, 0x32d0, 0x3b42);
  asm volatile("vfnmsac.vv v1, v2, v3, v0.t");
  //              -0.2739,  0.5967,  0.5264, -0.6475,  0.8877, -0.4927, -0.7563,
  //              -0.3911,  0.7451,  0.1733,  0.0698,  0.1917, -0.0681, -1.0459,
  //              0.2129,  1.0088
  VCMP_U16(4, v1, 0xb462, 0x38c6, 0x3836, 0xb92e, 0x3b1a, 0xb7e2, 0xba0d,
           0xb642, 0x39f6, 0x318a, 0x2c77, 0x3223, 0xac5b, 0xbc2f, 0x32d0,
           0x3c09);

  VSET(16, e32, m1);
  //               0.11577118, -0.10074481,  0.13861528,  0.44782066,
  //               0.42196107, -0.67597556,  0.34948668, -0.87903690,
  //               -0.34136006, -0.19722189,  0.76997000, -0.68663412,
  //               0.45603558,  0.60629857, -0.86984915, -0.08019307
  VLOAD_32(v2, 0x3ded1971, 0xbdce534c, 0x3e0df12a, 0x3ee548c0, 0x3ed80b48,
           0xbf2d0cbc, 0x3eb2efeb, 0xbf610890, 0xbeaec6bf, 0xbe49f489,
           0x3f451cc1, 0xbf2fc741, 0x3ee97d7f, 0x3f1b3662, 0xbf5eae6f,
           0xbda43c43);
  //              -0.38970658,  0.40460527,  0.69067985, -0.98108912,
  //              0.47494572, -0.34277225, -0.54462087, -0.90492284, 0.60100728,
  //              -0.02819708, -0.46859986,  0.87238866,  0.46812481,
  //              0.49922746,  0.97036403,  0.04279163
  VLOAD_32(v3, 0xbec7879f, 0x3ecf286c, 0x3f30d065, 0xbf7b28a8, 0x3ef32c16,
           0xbeaf7fd8, 0xbf0b6c46, 0xbf67a906, 0x3f19db9d, 0xbce6fd92,
           0xbeefec52, 0x3f5f54dd, 0x3eefae0e, 0x3eff9abe, 0x3f7869c7,
           0x3d2f4647);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               0.79804420, -0.70010293, -0.51047552,  0.38566175,
  //               0.15318950,  0.15531392, -0.20705318, -0.82493448,
  //               0.12047531,  0.57526720,  0.23939800, -0.19725421,
  //               0.15403098,  0.03931713, -0.45930895, -0.15395784
  VLOAD_32(v1, 0x3f4c4ca0, 0xbf3339f2, 0xbf02ae86, 0x3ec57575, 0x3e1cddb5,
           0x3e1f0a9d, 0xbe5405c0, 0xbf532ee8, 0x3df6bbc3, 0x3f1344b6,
           0x3e7524c0, 0xbe49fd02, 0x3e1dba4c, 0x3d210b00, 0xbeeb2a8b,
           0xbe1da720);
  asm volatile("vfnmsac.vv v1, v2, v3, v0.t");
  //               0.79804420, -0.65934104, -0.51047552,  0.82501376,
  //               0.15318950, -0.07639174, -0.20705318, -1.62039506,
  //               0.12047531,  0.56970614,  0.23939800,  0.40175763,
  //               0.15403098, -0.26336378, -0.45930895, -0.15052626
  VCMP_U32(5, v1, 0x3f4c4ca0, 0xbf28ca93, 0xbf02ae86, 0x3f53341a, 0x3e1cddb5,
           0xbd9c7345, 0xbe5405c0, 0xbfcf691b, 0x3df6bbc3, 0x3f11d843,
           0x3e7524c0, 0x3ecdb32c, 0x3e1dba4c, 0xbe86d79e, 0xbeeb2a8b,
           0xbe1a238e);

  VSET(16, e64, m1);
  //              -0.1779684802061718,  0.1122733699429854, -0.0166033088608786,
  //              -0.0418350503858864,  0.0809510021720363, -0.9993917101510512,
  //              -0.2139048161619248,  0.7196716914796224,  0.6489783595942558,
  //              0.5950689618839839, -0.7376256302221853, -0.5442228345597713,
  //              -0.8234113806545975, -0.6424001059348645, -0.3817524674245201,
  //              -0.8801262923106541
  VLOAD_64(v2, 0xbfc6c7abd11a2788, 0x3fbcbdf2941de8b0, 0xbf91007532405e80,
           0xbfa56b675a77c100, 0x3fb4b93472e84630, 0xbfeffb0452dfc0ba,
           0xbfcb613ba6efa978, 0x3fe7078ced586224, 0x3fe4c46e43c89c1c,
           0x3fe30ace10450114, 0xbfe79aa110cfdc92, 0xbfe16a46018575da,
           0xbfea5962d2e21a3e, 0xbfe48e8aaabdfd5e, 0xbfd86ea1e6b05c10,
           0xbfec29fe9d3a5e2c);
  //               0.6809772463364707, -0.3512739833826983, -0.3746023351803702,
  //               -0.7912172181005324,  0.8292434726428350, 0.4103374079106952,
  //               -0.0850673796598582, -0.5834949864830523,
  //               -0.9215678788036654,  0.4412210589054084, 0.3537359089001260,
  //               -0.4889461402031243,  0.2341577339668230, 0.0593866008892341,
  //               -0.4825773777931026,  0.8989772522533539
  VLOAD_64(v3, 0x3fe5ca90cb4aba98, 0xbfd67b45dfa41e18, 0xbfd7f97c12a6b704,
           0xbfe951a6c578c3ac, 0x3fea89299b6d84b0, 0x3fda42f7d4d35178,
           0xbfb5c6f9cd987320, 0xbfe2abfdad8a63b6, 0xbfed7d7beb902fcc,
           0x3fdc3cf7409388b4, 0x3fd6a39bf009666c, 0xbfdf4ae4c06b61e4,
           0x3fcdf8e170bf19c0, 0x3fae67eba9479c60, 0xbfdee28c39da4ac0,
           0x3fecc46bf148d5ca);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               0.2213384305747967, -0.6962211546566610, -0.0896076892809434,
  //               -0.1334142611967066,  0.1988436916560323,
  //               -0.3391391007320459, -0.6137202819751713, 0.6759552396290200,
  //               -0.7798663937316326, -0.1025181838739857, 0.5296250728149803,
  //               0.8832422045338422,  0.8373555508937671, -0.8622529212135799,
  //               0.4241832213372883,  0.7769982087360683
  VLOAD_64(v1, 0x3fcc54d154555708, 0xbfe6477196411436, 0xbfb6f0878eee8940,
           0xbfc113b7f0547630, 0x3fc973b5c856db48, 0xbfd5b4747c9c185c,
           0xbfe3a398b77f3552, 0x3fe5a16ce1f8870a, 0xbfe8f4aa5e0a7552,
           0xbfba3ea1b6fbece0, 0x3fe0f2b047dc3902, 0x3fec438527dd6ef6,
           0x3feacb9dde46cf34, 0xbfeb9793702fc4f0, 0x3fdb25d161c9f510,
           0x3fe8dd2b58f24dc8);
  asm volatile("vfnmsac.vv v1, v2, v3, v0.t");
  //               0.2213384305747967, -0.6567824407689892, -0.0896076892809434,
  //               -0.1665148733821233,  0.1988436916560323, 0.0709487030987733,
  //               -0.6137202819751713,  1.0958800635211576,
  //               -0.7798663937316326, -0.3650751413581792, 0.5296250728149803,
  //               0.6171465501654385,  0.8373555508937671, -0.8241029625112244,
  //               0.4241832213372883,  1.5682117246334322
  VCMP_U64(6, v1, 0x3fcc54d154555708, 0xbfe5045c9bf61361, 0xbfb6f0878eee8940,
           0xbfc5505bffbca57e, 0x3fc973b5c856db48, 0x3fb229b1b780ba72,
           0xbfe3a398b77f3552, 0x3ff188b9889296a1, 0xbfe8f4aa5e0a7552,
           0xbfd75d64202dd23c, 0x3fe0f2b047dc3902, 0x3fe3bfaa1f3997d0,
           0x3feacb9dde46cf34, 0xbfea5f0d2d10b7b0, 0x3fdb25d161c9f510,
           0x3ff917652d6811d0);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE3(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                             -0.4771
  BOX_HALF_IN_DOUBLE(dscalar_16, 0xb7a2);
  //              -0.6172,  0.8584, -0.1088, -0.6719,  0.3579,  0.5889,  0.1724,
  //              -0.5239, -0.5732, -0.6167,  0.8271, -0.7334,  0.3489, -0.7607,
  //              -0.7788, -0.5264
  VLOAD_16(v2, 0xb8f0, 0x3ade, 0xaef7, 0xb960, 0x35ba, 0x38b6, 0x3184, 0xb831,
           0xb896, 0xb8ef, 0x3a9e, 0xb9de, 0x3595, 0xba16, 0xba3b, 0xb836);
  //               0.0186,  0.9351,  0.6201,  0.9463,  0.2512,  0.5786,  0.9424,
  //               -0.5132, -0.7646,  0.0194, -0.2507, -0.2905,  0.3452,
  //               -0.7803, -0.7666, -0.1387
  VLOAD_16(v1, 0x24c1, 0x3b7b, 0x38f6, 0x3b92, 0x3405, 0x38a1, 0x3b8a, 0xb81b,
           0xba1e, 0x24f6, 0xb403, 0xb4a6, 0x3586, 0xba3e, 0xba22, 0xb070);
  asm volatile("vfnmsac.vf v1, %[A], v2" ::[A] "f"(dscalar_16));
  //              -0.2759,  1.3447,  0.5684,  0.6260,  0.4219,  0.8594,  1.0244,
  //              -0.7632, -1.0381, -0.2749,  0.1438, -0.6406,  0.5117, -1.1426,
  //              -1.1387, -0.3899
  VCMP_U16(7, v1, 0xb46a, 0x3d61, 0x388c, 0x3902, 0x36c0, 0x3ae0, 0x3c19,
           0xba1b, 0xbc27, 0xb466, 0x309a, 0xb920, 0x3818, 0xbc93, 0xbc8d,
           0xb63d);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -0.73549986
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0xbf3c49b8);
  //               0.74252719,  0.73023552,  0.75118375,  0.04020444,
  //               -0.77184784, -0.41120139, -0.57577437, -0.15976480,
  //               -0.05041125,  0.42673740,  0.88473374, -0.49891368,
  //               -0.84324479, -0.26009968, -0.01877740, -0.13754985
  VLOAD_32(v2, 0x3f3e1643, 0x3f3af0b7, 0x3f404d94, 0x3d24ad6a, 0xbf4597d2,
           0xbed288fd, 0xbf1365f3, 0xbe239962, 0xbd4e7c07, 0x3eda7d53,
           0x3f627de9, 0xbeff719d, 0xbf57dee4, 0xbe852bc9, 0xbc99d30f,
           0xbe0cd9de);
  //               0.89538908,  0.68592542,  0.67501348,  0.08327232,
  //               0.28473541, -0.93230879, -0.77235961, -0.92498165,
  //               -0.55227244,  0.97729182,  0.28253901,  0.45306230,
  //               -0.50359881,  0.40307203, -0.65891176, -0.59297264
  VLOAD_32(v1, 0x3f653838, 0x3f2f98cf, 0x3f2ccdaf, 0x3daa8aad, 0x3e91c8d7,
           0xbf6eabca, 0xbf45b95c, 0xbf6ccb99, 0xbf0d61ba, 0x3f7a2fcc,
           0x3e90a8f4, 0x3ee7f7c8, 0xbf00ebda, 0x3ece5f75, 0xbf28ae71,
           0xbf17cd0e);
  asm volatile("vfnmsac.vf v1, %[A], v2" ::[A] "f"(dscalar_32));
  //               1.44151771,  1.22301352,  1.22750902,  0.11284268,
  //               -0.28295860, -1.23474741, -1.19584155, -1.04248869,
  //               -0.58934993,  1.29115713,  0.93326056,  0.08611137,
  //               -1.12380528,  0.21176875, -0.67272252, -0.69414055
  VCMP_U32(8, v1, 0x3fb883a7, 0x3f9c8bb5, 0x3f9d1f04, 0x3de71a10, 0xbe90dff2,
           0xbf9e0c34, 0xbf991156, 0xbf857045, 0xbf16dfa3, 0x3fa544a3,
           0x3f6eea2a, 0x3db05b27, 0xbf8fd8da, 0x3e58d9e8, 0xbf2c378b,
           0xbf31b332);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.5178244899339752
  BOX_DOUBLE_IN_DOUBLE(dscalar_64, 0x3fe09204aa2ab2a0);
  //                0.8646249694399413,  0.0049558737185129, 0.9278624830778543,
  //                -0.8820434014846885,  0.9252937592855630,
  //                -0.0640564429957495, -0.9483662154664578,
  //                0.6036726974274773,  0.6321354499926264, 0.8250130840364809,
  //                0.1494192541908572,  0.0196333207724690,
  //                -0.2272946521816408,  0.9289723385226867,
  //                -0.5162193242581365, -0.3917544955022987
  VLOAD_64(v2, 0x3febab01fbe195e4, 0x3f744c9c38b4b600, 0x3fedb10ca98026d0,
           0xbfec39b31560f050, 0x3fed9c01a86a6166, 0xbfb06600c7c3cc10,
           0xbfee59041b01e946, 0x3fe35149679e0d42, 0x3fe43a741f8b89d2,
           0x3fea6681d6d6ae5e, 0x3fc3202b8d123b90, 0x3f941ac1da84be40,
           0xbfcd17fdbcd68200, 0x3fedba24329afe9c, 0xbfe084de63680fb2,
           0xbfd91281728f9314);
  //                0.3888129269587612, -0.8225750100551035, 0.8430062678626642,
  //                -0.6316792665412014, -0.6696614660277347,
  //                0.6130084754374303, -0.2295750183537659, 0.1572393304616742,
  //                -0.7542147373874082,  0.6149250820738357,
  //                0.1236692515687874,  0.9290168852760794,
  //                -0.0433411597165929, -0.8422695068160440,
  //                0.6519328829008422, -0.3347506024828231
  VLOAD_64(v1, 0x3fd8e24f9d6331d4, 0xbfea5288d3d6317c, 0x3feaf9e847d9618e,
           0xbfe436b76feb621e, 0xbfe56ddde1ff608c, 0x3fe39dc3f345962e,
           0xbfcd62b6d5e76d58, 0x3fc4206b1afd2970, 0xbfe82286f1e7af48,
           0x3fe3ad775d9fe964, 0x3fbfa8c9bf023cb0, 0x3fedba819e762954,
           0xbfa630cfff1b61a0, 0xbfeaf3df2e462cb6, 0x3fe4dca25967e02c,
           0xbfd56c8dca7eb8ac);
  asm volatile("vfnmsac.vf v1, %[A], v2" ::[A] "f"(dscalar_64));
  //               -0.0589110568256553, -0.8251412828355696, 0.3625363508340025,
  //               -0.1749355920677641, -1.1488012349688719, 0.6461784703586890,
  //               0.2615122334407671, -0.1553571761707763, -1.0815499543490239,
  //               0.1877131026437891,  0.0462963024810918,  0.9188502709613655,
  //               0.0743575776140855, -1.3233141341743264,  0.9192438911788732,
  //               -0.1318905306700034
  VCMP_U64(9, v1, 0xbfae29970ce0c2e6, 0xbfea678eb10b76d9, 0x3fd733cbaa9c5dc5,
           0xbfc6644a1b6b315b, 0xbff2617d675cbb41, 0x3fe4ad7e78b23c6a,
           0x3fd0bc9dce8872e3, 0xbfc3e2be736d1b43, 0xbff14e07532eb5a9,
           0x3fc806fba27160c3, 0x3fa7b4262229fd93, 0x3fed6738aef664ca,
           0x3fb30919240ff186, 0xbff52c4b7109d007, 0x3fed6a722a352743,
           0xbfc0e1c9f5f09ba4);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE4(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                             -0.4771
  BOX_HALF_IN_DOUBLE(dscalar_16, 0xb7a2);
  //               -0.6172,  0.8584, -0.1088, -0.6719,  0.3579,  0.5889, 0.1724,
  //               -0.5239, -0.5732, -0.6167,  0.8271, -0.7334,  0.3489,
  //               -0.7607, -0.7788, -0.5264
  VLOAD_16(v2, 0xb8f0, 0x3ade, 0xaef7, 0xb960, 0x35ba, 0x38b6, 0x3184, 0xb831,
           0xb896, 0xb8ef, 0x3a9e, 0xb9de, 0x3595, 0xba16, 0xba3b, 0xb836);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                0.0186,  0.9351,  0.6201,  0.9463,  0.2512,  0.5786, 0.9424,
  //                -0.5132, -0.7646,  0.0194, -0.2507, -0.2905,  0.3452,
  //                -0.7803, -0.7666, -0.1387
  VLOAD_16(v1, 0x24c1, 0x3b7b, 0x38f6, 0x3b92, 0x3405, 0x38a1, 0x3b8a, 0xb81b,
           0xba1e, 0x24f6, 0xb403, 0xb4a6, 0x3586, 0xba3e, 0xba22, 0xb070);
  asm volatile("vfnmsac.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_16));
  //                0.0186,  1.3447,  0.6201,  0.6260,  0.2512,  0.8594, 0.9424,
  //                -0.7632, -0.7646, -0.2749, -0.2507, -0.6406,  0.3452,
  //                -1.1426, -0.7666, -0.3899
  VCMP_U16(10, v1, 0x24c1, 0x3d61, 0x38f6, 0x3902, 0x3405, 0x3ae0, 0x3b8a,
           0xba1b, 0xba1e, 0xb466, 0xb403, 0xb920, 0x3586, 0xbc93, 0xba22,
           0xb63d);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -0.73549986
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0xbf3c49b8);
  //                0.74252719,  0.73023552,  0.75118375,  0.04020444,
  //                -0.77184784, -0.41120139, -0.57577437, -0.15976480,
  //                -0.05041125,  0.42673740,  0.88473374, -0.49891368,
  //                -0.84324479, -0.26009968, -0.01877740, -0.13754985
  VLOAD_32(v2, 0x3f3e1643, 0x3f3af0b7, 0x3f404d94, 0x3d24ad6a, 0xbf4597d2,
           0xbed288fd, 0xbf1365f3, 0xbe239962, 0xbd4e7c07, 0x3eda7d53,
           0x3f627de9, 0xbeff719d, 0xbf57dee4, 0xbe852bc9, 0xbc99d30f,
           0xbe0cd9de);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                0.89538908,  0.68592542,  0.67501348,  0.08327232,
  //                0.28473541, -0.93230879, -0.77235961, -0.92498165,
  //                -0.55227244,  0.97729182,  0.28253901,  0.45306230,
  //                -0.50359881,  0.40307203, -0.65891176, -0.59297264
  VLOAD_32(v1, 0x3f653838, 0x3f2f98cf, 0x3f2ccdaf, 0x3daa8aad, 0x3e91c8d7,
           0xbf6eabca, 0xbf45b95c, 0xbf6ccb99, 0xbf0d61ba, 0x3f7a2fcc,
           0x3e90a8f4, 0x3ee7f7c8, 0xbf00ebda, 0x3ece5f75, 0xbf28ae71,
           0xbf17cd0e);
  asm volatile("vfnmsac.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_32));
  //                0.89538908,  1.22301352,  0.67501348,  0.11284268,
  //                0.28473541, -1.23474741, -0.77235961, -1.04248869,
  //                -0.55227244,  1.29115713,  0.28253901,  0.08611137,
  //                -0.50359881,  0.21176875, -0.65891176, -0.69414055
  VCMP_U32(11, v1, 0x3f653838, 0x3f9c8bb5, 0x3f2ccdaf, 0x3de71a10, 0x3e91c8d7,
           0xbf9e0c34, 0xbf45b95c, 0xbf857045, 0xbf0d61ba, 0x3fa544a3,
           0x3e90a8f4, 0x3db05b27, 0xbf00ebda, 0x3e58d9e8, 0xbf28ae71,
           0xbf31b332);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.5178244899339752
  BOX_DOUBLE_IN_DOUBLE(dscalar_64, 0x3fe09204aa2ab2a0);
  //                 0.8646249694399413,  0.0049558737185129,
  //                 0.9278624830778543, -0.8820434014846885,
  //                 0.9252937592855630, -0.0640564429957495,
  //                 -0.9483662154664578,  0.6036726974274773,
  //                 0.6321354499926264,  0.8250130840364809,
  //                 0.1494192541908572,  0.0196333207724690,
  //                 -0.2272946521816408,  0.9289723385226867,
  //                 -0.5162193242581365, -0.3917544955022987
  VLOAD_64(v2, 0x3febab01fbe195e4, 0x3f744c9c38b4b600, 0x3fedb10ca98026d0,
           0xbfec39b31560f050, 0x3fed9c01a86a6166, 0xbfb06600c7c3cc10,
           0xbfee59041b01e946, 0x3fe35149679e0d42, 0x3fe43a741f8b89d2,
           0x3fea6681d6d6ae5e, 0x3fc3202b8d123b90, 0x3f941ac1da84be40,
           0xbfcd17fdbcd68200, 0x3fedba24329afe9c, 0xbfe084de63680fb2,
           0xbfd91281728f9314);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                 0.3888129269587612, -0.8225750100551035,
  //                 0.8430062678626642, -0.6316792665412014,
  //                 -0.6696614660277347,  0.6130084754374303,
  //                 -0.2295750183537659,  0.1572393304616742,
  //                 -0.7542147373874082,  0.6149250820738357,
  //                 0.1236692515687874,  0.9290168852760794,
  //                 -0.0433411597165929, -0.8422695068160440,
  //                 0.6519328829008422, -0.3347506024828231
  VLOAD_64(v1, 0x3fd8e24f9d6331d4, 0xbfea5288d3d6317c, 0x3feaf9e847d9618e,
           0xbfe436b76feb621e, 0xbfe56ddde1ff608c, 0x3fe39dc3f345962e,
           0xbfcd62b6d5e76d58, 0x3fc4206b1afd2970, 0xbfe82286f1e7af48,
           0x3fe3ad775d9fe964, 0x3fbfa8c9bf023cb0, 0x3fedba819e762954,
           0xbfa630cfff1b61a0, 0xbfeaf3df2e462cb6, 0x3fe4dca25967e02c,
           0xbfd56c8dca7eb8ac);
  asm volatile("vfnmsac.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_64));
  //                0.3888129269587612, -0.8251412828355696, 0.8430062678626642,
  //                -0.1749355920677641, -0.6696614660277347,
  //                0.6461784703586890, -0.2295750183537659,
  //                -0.1553571761707763, -0.7542147373874082,
  //                0.1877131026437891,  0.1236692515687874, 0.9188502709613655,
  //                -0.0433411597165929, -1.3233141341743264,
  //                0.6519328829008422, -0.1318905306700034
  VCMP_U64(12, v1, 0x3fd8e24f9d6331d4, 0xbfea678eb10b76d9, 0x3feaf9e847d9618e,
           0xbfc6644a1b6b315b, 0xbfe56ddde1ff608c, 0x3fe4ad7e78b23c6a,
           0xbfcd62b6d5e76d58, 0xbfc3e2be736d1b43, 0xbfe82286f1e7af48,
           0x3fc806fba27160c3, 0x3fbfa8c9bf023cb0, 0x3fed6738aef664ca,
           0xbfa630cfff1b61a0, 0xbff52c4b7109d007, 0x3fe4dca25967e02c,
           0xbfc0e1c9f5f09ba4);
};

int main(void) {
  enable_vec();
  enable_fp();

  TEST_CASE1();
  TEST_CASE2();
  TEST_CASE3();
  TEST_CASE4();

  EXIT_CHECK();
}
